/* user.c : User processes
 */

#include <kernel.h>

#define OUT_SZ 1024

//void producer(void);
//void consumer(void);
//void producer2(void);
//void producer3(void);

//void sleeper1(void);
//void sleeper2(void);


/*
 * Extended Consumer
**/

void consumerx(void);

/* Root user process. 
 * Extended Producer
*/


// root process id
int root_pid;

extern void root(void){
	
	
	
	int pid[4];
	int msg, res, me;
	char out[OUT_SZ];
	
	root_pid = sysgetpid();
	
	bzero(out, OUT_SZ);
	sprintf(out, "Process %d (root) is alive.\n", root_pid);
	sysputs(out);

	
	
	int i;
	// create consumer processes
	for(i = 0; i < 4; i++){
		pid[i] = syscreate(consumerx, STDSTACKSIZ);
		
		bzero(out, OUT_SZ);
		sprintf(out, "Process %d (root) created process %d of 4: %d\n", root_pid, (i+1), pid[i]);
		sysputs(out);
	}
	
	syssleep(4000);
	
	// send out sleep times
	msg = 10*1000;
	syssend(pid[2], &msg, sizeof(int));
	
	msg = 7*1000;
	syssend(pid[1], &msg, sizeof(int));
	
	msg = 20*1000;
	syssend(pid[0], &msg, sizeof(int));
	
	msg = 27*1000;
	syssend(pid[3], &msg, sizeof(int));
	
	// this should fail
	res = sysrecv(&pid[3], &msg, sizeof(int));
	
	
	bzero(out, OUT_SZ);
	sprintf(out, "Process %d (root) sysrecv() returned %d\n", root_pid, res);
	sysputs(out);
	
	
}


void consumerx(void){
	int me;
	int pid;
	int msg;
	int res;
	char out[OUT_SZ];
	
	me = sysgetpid();
	
	bzero(out, OUT_SZ);
	sprintf(out, "Process %d is alive.\n", me);
	sysputs(out);
	
	
	syssleep(5000);
	
	// get my sleep time
	res = sysrecv(&root_pid, &msg, sizeof(int));
	
	if(res == -1){
		
		bzero(out, OUT_SZ);
		sprintf(out, "Process %d sysrecv() returned -1\n", me);
		sysputs(out);
		return;
	}
	

	bzero(out, OUT_SZ);
	sprintf(out, "Process %d message received, sleeping for %dms\n", me, msg);
	sysputs(out);
	
	// sleep for the requested duration
	syssleep(msg);
	
	
	bzero(out, OUT_SZ);
	sprintf(out, "Process %d sleeping complete, exiting...\n", me);
	sysputs(out);
	
	 
}


/*
 * The idle process
 * It idles.
**/
extern void idle(void){
	while(TRUE){
		// TODO: hlt
	}
}


/*
void sleeper1(void){
	int i = 0;
	
	kprintf("Sleeper1 is process %d\n", sysgetpid());
	
	while(1){
		i++;
		kprintf("Sleeper1 - %d\n", (i++));
		syssleep(20000);
		
	}	
	
}

void sleeper2(void){
	int i = 0;
	
	kprintf("Sleeper2 is process %d\n", sysgetpid());
	
	while(1){
		i++;
		kprintf("Sleeper2 - %d\n", (i++));
		syssleep(20000);
		
	}
}


void producer(){
	int len = 16;
	void* mem = kmalloc(len);
	int* coolermem = (int*)mem;
	coolermem[0] = 1337;
	coolermem[1] = 1338;
	coolermem[2] = 1339;
	coolermem[3] = 1340;

	int rc = syssend(103, mem, len);
	 kprintf("Producer sent %d bytes \n", rc);
	kprintf("I'm still here!");
	while(1) ;

	return;
}

void producer2(){
	int len = 16;
	void* mem = kmalloc(len);
	int* coolermem = (int*)mem;
	coolermem[0] = 22;
	coolermem[1] = 33;
	coolermem[2] = 44;
	coolermem[3] = 55;
	int rc = syssend(105, mem, len);
	 kprintf("Producer2 sent %d bytes \n", rc);
	while(1) sysyield();
}
void producer3(){
	int len = 16;
	void* mem = kmalloc(len);
	int* coolermem = (int*)mem;
	coolermem[0] = 66;
	coolermem[1] = 77;
	coolermem[2] = 88;
	coolermem[3] = 99;
	kprintf("Calling syssend\n");
	int rc = syssend(105, mem, len);
	 kprintf("Producer3 sent %d bytes \n", rc);
	while(1) sysyield();
}

void consumer(){

	int len = 16;
	void* buf = kmalloc(len);
	unsigned int* pid = (unsigned int*)kmalloc(4);
	*pid = 103;
	kprintf("Calling sysrecv\n");
	int rc = sysrecv(pid, buf, len);
	kprintf("Consumer received %d bytes\n", rc);
	int* coolermem = (int*)buf;
	kprintf("received from pid: %d buf[0]: %d, buf[1]: %d, buf[2]: %d, buf[3]: %d\n", *pid, coolermem[0], coolermem[1], coolermem[2], coolermem[3]);
	//while(1);	
//	int len = 16;
//	void* buf = kmalloc(len);
//	unsigned int* pid = (unsigned int*)kmalloc(4);
//	*pid = 103;
//	len = -100;
//	kprintf("Calling sysrecv with negative len\n");
//	int rc = sysrecv(pid, buf, len);
//	kprintf("Consumer received %d bytes\n", rc);
//	int* coolermem = (int*)buf;
//	kprintf("received from pid: %d buf[0]: %d, buf[1]: %d, buf[2]: %d, buf[3]: %d\n", *pid, coolermem[0], coolermem[1], coolermem[2], coolermem[3]);
//	while(1);	
	kprintf("Second process is alive, but now returning and dying\n");

	return;
}

*/

